using System;
using System.Collections.Generic;
using System.IO;
using GGEditor.API;
using GGEditor.API.Editors;
using GGEditor.API.Plugins;

namespace GGEditor.Core.Documents
{
	public class ExporterManager
	{
		private readonly IDictionary<string, IFileExporterDefinition> definitionsByExtension =
			new Dictionary<string, IFileExporterDefinition>();

		private readonly IDictionary<string, IFileExporterDefinition> definitionsByName =
			new Dictionary<string, IFileExporterDefinition>();

		private readonly IDictionary<Type, IFileExporterDefinition> definitionsByModelType =
			new Dictionary<Type, IFileExporterDefinition>();

		protected void Register(IFileExporterDefinition definition)
		{
			definitionsByExtension[definition.FileExtension] = definition;
			definitionsByName[definition.Name] = definition;
			definitionsByModelType[definition.ModelType] = definition;
		}

		protected void Unregister(IFileExporterDefinition definition)
		{
			definitionsByExtension.Remove(definition.FileExtension);
			definitionsByName.Remove(definition.Name);
			definitionsByModelType.Remove(definition.ModelType);
		}

		public void Save(IEditorModel model, string filePath)
		{
			string fileExtension = Path.GetExtension(filePath);
			if (fileExtension.StartsWith("."))
				fileExtension = fileExtension.Substring(1);

			IFileExporterDefinition definition = definitionsByExtension[fileExtension];

			definition.Exporter.Export(model, filePath);
		}

		#region XmlNodeObjectFactory

		[XmlNodeObjectFactory(Name = "ExporterManager")]
		public class DocumentManagerFactory : IXmlNodeObjectFactory
		{
			#region Implementation of IXmlNodeObjectFactory

			public object Build(IPluginNode pluginNode, IDictionary<string, string> attributes)
			{
				pluginNode.ChildAdded += OnChildAdded;
				pluginNode.ChildRemoved += OnChildRemoved;
				return Instance;
			}

			#endregion

			void OnChildAdded(IPluginNode node, IPluginNode child, int position)
			{
				Instance.Register(child.Object as IFileExporterDefinition);
			}

			void OnChildRemoved(IPluginNode node, IPluginNode child, int position)
			{
				Instance.Unregister(child.Object as IFileExporterDefinition);
			}
		}

		#endregion

		#region Singleton

		private ExporterManager() { }

		private static ExporterManager instance = new ExporterManager();

		public static ExporterManager Instance
		{
			get { return instance; }
		}

		#endregion
	}
}